package com.base.cn.platform.os.common.utils.file;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 文件下载工具
 *
 * @author zjh
 * @since 2018-10-10
 */
@Slf4j
public final class FileDownloadUtil {


    /**
     *
     * @param srcfile srcfile压缩文件信息  List<Map<String, Object>> 需要压缩的文件列表(map中需包含，name文件名，inputStream文件的输入流)
     * @param expName 生成压缩文件名
     * @throws Exception
     */
    public static void createRarInputStream(HttpServletResponse response,List<Map<String, Object>> srcfile, String expName) throws Exception {
        String fileName= expName + ".zip";
        writeRar(fileName,response);
        zipFilesInputStream(srcfile,response.getOutputStream());//生成压缩文件
    }


    /**
     * 创建多文件压缩包 (响应时间长)
     *
     * @param srcfile  文件file集合
     * @param expName  文件名
     */
    public static ResponseEntity<byte[]> createRar(List<Map<String, Object>> srcfile, String expName) throws Exception {
        String fileName= expName + ".zip";
       return zipFiles(srcfile,fileName);//生成压缩文件
    }

    /**
     * 获取网络请求文件的流
     * @param url 文件的地址
     * @return
     * @throws Exception
     */
    public static InputStream getInputStream(String url) throws Exception{
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setReadTimeout(5000);
        connection.setConnectTimeout(5000);
        connection.setRequestMethod("GET");
        InputStream inputStream =null;
        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            inputStream = connection.getInputStream();
        }
        return inputStream;
    }

    /**
     * 压缩文件
     * @param srcfile List<Map<String, Object>> 需要压缩的文件列表(map中需包含，name文件名，inputStream文件的输入流)
     * @param fileName File 压缩后的文件
     * @author
     */
    public static ResponseEntity<byte[]> zipFiles(List<Map<String, Object>> srcfile, String  fileName) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ZipOutputStream out =new ZipOutputStream(bos);
        streamProcessing(out,srcfile);
        return  commonReturnWord(bos,fileName);
    }

    /**
     * 压缩文件
     * @param srcfile List<Map<String, Object>> 需要压缩的文件列表(map中需包含，name文件名，inputStream文件的输入流)
     * @param zos File 压缩后的文件
     * @author
     */
    public static void zipFilesInputStream(List<Map<String, Object>> srcfile, OutputStream zos) throws Exception {

        ZipOutputStream out = new ZipOutputStream(zos);
        streamProcessing(out,srcfile);

    }


    /**
     * 递归删除文件夹下内容
     *
     * @param file
     */
    public static void deleteFile(File file) {
        if (file.exists()) {
            if (file.isFile()) {
                file.delete();
            } else if (file.isDirectory()) {
                File files[] = file.listFiles();
                for (int i = 0; i < files.length; i++) {
                    deleteFile(files[i]);
                }
            }
            file.delete();
        } else {
            log.info("所删除的文件不存在！"+'\n');
        }
    }

    public static ResponseEntity<byte[]> commonReturnWord(ByteArrayOutputStream os, String fileName) throws UnsupportedEncodingException {
        HttpHeaders headers = new HttpHeaders();
        fileName = new String(fileName.getBytes("gbk"), "iso-8859-1");
        headers.setContentDispositionFormData("attachment", fileName);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<>(os.toByteArray(), headers, HttpStatus.OK);
    }

    /**
     * 处理流
     */
    private static void streamProcessing(ZipOutputStream out,List<Map<String, Object>> srcfile){
        byte[] buf = new byte[1024];
        try {
            for (int i = 0; i < srcfile.size(); i++) {
                Map<String, Object> file = srcfile.get(i);
                out.putNextEntry(new ZipEntry(file.get("name").toString()));
                InputStream inputStream = (InputStream) file.get("inputStream");
                int len;
                while ((len = inputStream.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.closeEntry();
                inputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 输出文件的输出头
     * @param fileName 文件
     * @param response
     */
    private static void writeRar(String fileName, HttpServletResponse response){
        try {
            String filename = new String(fileName.getBytes("gbk"), "iso-8859-1");
            // 设置response的Header
            response.setContentType("application/zip");
            response.addHeader("Content-Disposition", "attachment;filename=" + filename + "");  //转码之后下载的文件不会出现中文乱码
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

